package com.jhgsys.internal.incentive.controller;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.jhgsys.internal.base.entity.BaseGoods;
import com.jhgsys.internal.base.service.IBaseGoodsService;
import com.jhgsys.internal.common.annotation.Log;
import com.jhgsys.internal.common.controller.BaseController;
import com.jhgsys.internal.common.entity.FebsConstant;
import com.jhgsys.internal.common.entity.FebsResponse;
import com.jhgsys.internal.common.entity.QueryRequest;
import com.jhgsys.internal.common.entity.FebsConstant;
import com.jhgsys.internal.common.exception.FebsException;
import com.jhgsys.internal.common.utils.BeanHelper;
import com.jhgsys.internal.common.utils.FebsUtil;
import com.jhgsys.internal.incentive.constant.IncentiveRewardConstant;
import com.jhgsys.internal.incentive.dto.IncentiveGoodsOrderDtlDto;
import com.jhgsys.internal.incentive.dto.IncentiveGoodsOrderDto;
import com.jhgsys.internal.incentive.dto.IncentiveGoodsOrderUserDto;
import com.jhgsys.internal.incentive.entity.IncentiveGoodsOrder;
import com.jhgsys.internal.incentive.entity.IncentiveGoodsOrderDtl;
import com.jhgsys.internal.incentive.entity.IncentiveGoodsOrderUser;
import com.jhgsys.internal.incentive.service.IIncentiveGoodsOrderDtlService;
import com.jhgsys.internal.incentive.service.IIncentiveGoodsOrderService;
import com.jhgsys.internal.incentive.service.IIncentiveGoodsOrderUserService;
import com.jhgsys.internal.system.dto.TenantDto;
import com.jhgsys.internal.system.entity.Tenant;
import com.jhgsys.internal.system.service.ITenantService;
import com.wuwenze.poi.ExcelKit;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.*;
import javax.validation.constraints.NotBlank;
import java.util.stream.Collectors;

/**
 * 安全奖i订单 Controller
 *
 * @author zhangwei
 * @date 2024-09-02 11:28:06
 */
@Slf4j
@Validated
@Controller
public class IncentiveGoodsOrderController extends BaseController {

    @Autowired
    private IIncentiveGoodsOrderService incentiveGoodsOrderService;

    @Autowired
    private IIncentiveGoodsOrderDtlService iIncentiveGoodsOrderDtlService;

    @Autowired
    private IIncentiveGoodsOrderUserService iIncentiveGoodsOrderUserService;

    @Autowired
    private IBaseGoodsService baseGoodsService;

    @Autowired
    private ITenantService tenantService;


    @GetMapping(FebsConstant.VIEW_PREFIX + "incentiveGoodsOrder")
    @RequiresPermissions("incentiveGoodsOrder:view")
    public String incentiveGoodsOrderIndex(Model model) {
        model.addAttribute("hasHeadCompanyRole", hasHeadCompanyRole());
        model.addAttribute("tenantList", getTenantList());
        model.addAttribute("currentTenantId", getCurrentTenantId());
        return FebsUtil.view("incentive/incentiveGoodsOrder/incentiveGoodsOrderList");
    }

    @GetMapping(FebsConstant.VIEW_PREFIX + "incentiveGoodsOrder/add")
    @RequiresPermissions("incentiveGoodsOrder:add")
    public String incentiveGoodsOrderAdd() {
        return FebsUtil.view("incentive/incentiveGoodsOrder/incentiveGoodsOrderEdit");
    }

    @GetMapping(FebsConstant.VIEW_PREFIX + "incentiveGoodsOrder/update/{id}")
    @RequiresPermissions("incentiveGoodsOrder:edit")
    public String incentiveGoodsOrderUpdate(Model model, @PathVariable("id") String id) {
        model.addAttribute("incentiveGoodsOrder", incentiveGoodsOrderService.findIncentiveGoodsOrderById(id));
        return FebsUtil.view("incentive/incentiveGoodsOrder/incentiveGoodsOrderEdit");
    }

    @GetMapping(FebsConstant.VIEW_PREFIX + "incentiveGoodsOrder/detail/{id}")
    public String incentiveGoodsOrderDetail(Model model, @PathVariable("id") String id) {
        IncentiveGoodsOrder incentiveGoodsOrderById = incentiveGoodsOrderService.findIncentiveGoodsOrderById(id);
        IncentiveGoodsOrderDto incentiveGoodsOrderDto = new IncentiveGoodsOrderDto();
        BeanUtils.copyProperties(incentiveGoodsOrderById,incentiveGoodsOrderDto);
        Tenant tenant = tenantService.getById(incentiveGoodsOrderById.getTenantId());
        if(null != tenant) {
            incentiveGoodsOrderDto.setTenantName(tenant.getTenantName());
        }
        IncentiveGoodsOrderDtl incentiveGoodsOrderDtl = new IncentiveGoodsOrderDtl();
        incentiveGoodsOrderDtl.setGoodsOrderId(id);
        List<IncentiveGoodsOrderDtl> incentiveGoodsOrderDtlList = iIncentiveGoodsOrderDtlService.findIncentiveGoodsOrderDtlList(incentiveGoodsOrderDtl);
        List<IncentiveGoodsOrderDtlDto> dtlDtoList = BeanHelper.copyWithCollection(incentiveGoodsOrderDtlList, IncentiveGoodsOrderDtlDto.class);
        incentiveGoodsOrderDto.setGoodsList(dtlDtoList);
        IncentiveGoodsOrderUser incentiveGoodsOrderUser = new IncentiveGoodsOrderUser();
        incentiveGoodsOrderUser.setGoodsOrderId(id);
        List<IncentiveGoodsOrderUser> incentiveGoodsOrderUserList = iIncentiveGoodsOrderUserService.findIncentiveGoodsOrderUserList(incentiveGoodsOrderUser);
        String tenantIds = incentiveGoodsOrderUserList.stream().map(IncentiveGoodsOrderUser::getTenantId).distinct().collect(Collectors.joining(StringPool.COMMA));
        List<IncentiveGoodsOrderUserDto> incentiveGoodsOrderUserDtos = BeanHelper.copyWithCollection(incentiveGoodsOrderUserList, IncentiveGoodsOrderUserDto.class);
        Tenant tenant1 = new Tenant();
        tenant1.setTenantId(tenantIds);
        List<TenantDto> tenantList = tenantService.findTenantList(tenant1);
        Map<String, String> map = tenantList.stream().collect(Collectors.toMap(Tenant::getTenantId, Tenant::getTenantName));
        incentiveGoodsOrderUserDtos.forEach(item -> item.setTenantName(map.getOrDefault(item.getTenantId(),"")));
        incentiveGoodsOrderDto.setUserList(incentiveGoodsOrderUserDtos);
        model.addAttribute("incentiveGoodsOrder", incentiveGoodsOrderDto);
        return FebsUtil.view("incentive/incentiveGoodsOrder/incentiveGoodsOrderDetail");
    }

    @GetMapping(FebsConstant.VIEW_PREFIX + "incentiveGoodsOrder/handOut/{id}")
    @RequiresPermissions("incentiveGoodsOrder:handOut")
    public String incentiveGoodsOrderHandOut(Model model, @PathVariable("id") String id) {
        IncentiveGoodsOrder incentiveGoodsOrderById = incentiveGoodsOrderService.findIncentiveGoodsOrderById(id);
        // 线上申请
        boolean isOnline = "2".equals(incentiveGoodsOrderById.getGoodsOrderType());
        model.addAttribute("isOnline", isOnline);
        IncentiveGoodsOrderDto dto = new IncentiveGoodsOrderDto();
        BeanUtils.copyProperties(incentiveGoodsOrderById, dto);
        // 申请人
        IncentiveGoodsOrderUser incentiveGoodsOrderUser = new IncentiveGoodsOrderUser();
        incentiveGoodsOrderUser.setGoodsOrderId(id);
        List<IncentiveGoodsOrderUser> incentiveGoodsOrderUserList = iIncentiveGoodsOrderUserService.findIncentiveGoodsOrderUserList(incentiveGoodsOrderUser);
        model.addAttribute("userList", incentiveGoodsOrderUserList);
        Set<String> nameSet = incentiveGoodsOrderUserList.stream().map(IncentiveGoodsOrderUser::getRealName).collect(Collectors.toSet());
        dto.setApplyUserNames(String.join("、", nameSet));
        model.addAttribute("incentiveGoodsOrder", dto);
        // 奖品子表数据
        IncentiveGoodsOrderDtl dtl = new IncentiveGoodsOrderDtl();
        dtl.setGoodsOrderId(id);
        List<IncentiveGoodsOrderDtl> incentiveGoodsOrderDtlList = iIncentiveGoodsOrderDtlService.findIncentiveGoodsOrderDtlList(dtl);
        if(!incentiveGoodsOrderDtlList.isEmpty()){
            String goodsIds = incentiveGoodsOrderDtlList.stream().map(IncentiveGoodsOrderDtl::getGoodsId).collect(Collectors.joining(StringPool.COMMA));
            BaseGoods baseGoods = new BaseGoods();
            baseGoods.setGoodsId(goodsIds);
            List<BaseGoods> baseGoodsList = baseGoodsService.findBaseGoodsList(baseGoods);
            List<IncentiveGoodsOrderDtlDto> dtlDtoList = incentiveGoodsOrderDtlList.stream().map(item -> {
                IncentiveGoodsOrderDtlDto dtlDto = new IncentiveGoodsOrderDtlDto();
                BeanUtils.copyProperties(item, dtlDto);
                BaseGoods findGoods = baseGoodsList.stream().filter(goods -> Objects.equals(item.getGoodsId(), goods.getGoodsId())).findFirst().orElse(null);
                if (null != findGoods) {
                    dtlDto.setInventory(findGoods.getInventory());
                    dtlDto.setLockNumber(findGoods.getLockNumber());
                }
                return dtlDto;
            }).collect(Collectors.toList());
            model.addAttribute("itemList", dtlDtoList);
        }
        return FebsUtil.view("incentive/incentiveGoodsOrder/incentiveGoodsOrderHandOut");
    }

    /**
     * 查询（所有）
     *
     * @author zhangwei
     * @date 2024-09-02 11:28:06
     */
    @GetMapping("incentiveGoodsOrder")
    @ResponseBody
    @RequiresPermissions("incentiveGoodsOrder:view")
    public FebsResponse getAllIncentiveGoodsOrders(IncentiveGoodsOrder incentiveGoodsOrder) {
        return new FebsResponse().success().data(incentiveGoodsOrderService.findIncentiveGoodsOrderList(incentiveGoodsOrder));
    }

    /**
     * 查询（分页）
     *
     * @author zhangwei
     * @date 2024-09-02 11:28:06
     */
    @GetMapping("incentiveGoodsOrder/list")
    @ResponseBody
    @RequiresPermissions("incentiveGoodsOrder:view")
    public FebsResponse incentiveGoodsOrderList(QueryRequest request, IncentiveGoodsOrderDto incentiveGoodsOrderDto) {
        Map<String, Object> dataTable = getDataTable(this.incentiveGoodsOrderService.findIncentiveGoodsOrderPage(request, incentiveGoodsOrderDto));
        return new FebsResponse().success().data(dataTable);
    }

    /**
     * 新增 IncentiveGoodsOrder
     *
     * @author zhangwei
     * @date 2024-09-02 11:28:06
     */
    @Log("新增IncentiveGoodsOrder")
    @PostMapping("incentiveGoodsOrder")
    @ResponseBody
    @RequiresPermissions("incentiveGoodsOrder:add")
    public FebsResponse addIncentiveGoodsOrder(@RequestBody IncentiveGoodsOrderDto incentiveGoodsOrderDto) throws FebsException {
        if (null == incentiveGoodsOrderDto.getUser()) {
            throw new FebsException("未选择申请人，请确认！");
        }
        if (incentiveGoodsOrderDto.getGoodsList().isEmpty()) {
            throw new FebsException("未选择奖品，请确认！");
        }
        for (IncentiveGoodsOrderDtlDto incentiveGoodsOrderDtlDto : incentiveGoodsOrderDto.getGoodsList()) {
            if (incentiveGoodsOrderDtlDto.getGoodsNumber() <= 0) {
                throw new FebsException("【" + incentiveGoodsOrderDtlDto.getGoodsName() + "】奖品数量不能小于或等于0，请确认！");
            }
            if(incentiveGoodsOrderDtlDto.getGoodsNumber() > incentiveGoodsOrderDtlDto. getInventory()){
                throw new FebsException("【" + incentiveGoodsOrderDtlDto.getGoodsName() + "】奖品数量不能超过在库数量，请确认！");
            }
        }
        try {
            if(StringUtils.isBlank(incentiveGoodsOrderDto.getTenantId())){
                incentiveGoodsOrderDto.setTenantId(getCurrentTenantId());
            }
            incentiveGoodsOrderDto.setCreatedBy(getCurrentUser().getUserName());
            this.incentiveGoodsOrderService.createIncentiveGoodsOrder(incentiveGoodsOrderDto);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "新增IncentiveGoodsOrder失败";
            log.error(message, e);
            throw new FebsException("".equals(e.getMessage()) || null == e.getMessage() ? message :e.getMessage());
        }
    }

    /**
     * 逻辑删除 IncentiveGoodsOrder
     *
     * @author zhangwei
     * @date 2024-09-02 11:28:06
     */
    @Log("逻辑删除IncentiveGoodsOrder")
    @GetMapping("incentiveGoodsOrder/delete/{id}")
    @ResponseBody
    @RequiresPermissions("incentiveGoodsOrder:delete")
    public FebsResponse deleteIncentiveGoodsOrder(@PathVariable("id") String incentiveGoodsOrderIds) throws FebsException {
        try {
            IncentiveGoodsOrder incentiveGoodsOrder = new IncentiveGoodsOrder();
            incentiveGoodsOrder.setDeletedBy(getCurrentUser().getUserName());
            incentiveGoodsOrder.setDeletedTime(new Date());
            incentiveGoodsOrder.setDeletedFlg(FebsConstant.INVALID);
            this.incentiveGoodsOrderService.deleteIncentiveGoodsOrder(incentiveGoodsOrder, incentiveGoodsOrderIds);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "删除IncentiveGoodsOrder失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 物理删除 IncentiveGoodsOrder
     *
     * @author zhangwei
     * @date 2024-09-02 11:28:06
     */
    @Log("物理删除IncentiveGoodsOrder")
    @GetMapping("incentiveGoodsOrder/physicallyDelete/{id}")
    @ResponseBody
    @RequiresPermissions("incentiveGoodsOrder:delete")
    public FebsResponse physicallyDeleteIncentiveGoodsOrder(@PathVariable("id") String incentiveGoodsOrderIds) throws FebsException {
        try {
            this.incentiveGoodsOrderService.physicallyDeleteIncentiveGoodsOrder(incentiveGoodsOrderIds);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "删除IncentiveGoodsOrder失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 修改 IncentiveGoodsOrder
     *
     * @author zhangwei
     * @date 2024-09-02 11:28:06
     */
    @Log("修改IncentiveGoodsOrder")
    @PostMapping("incentiveGoodsOrder/update")
    @ResponseBody
    @RequiresPermissions("incentiveGoodsOrder:edit")
    public FebsResponse updateIncentiveGoodsOrder(IncentiveGoodsOrder incentiveGoodsOrder) throws FebsException {
        try {
            incentiveGoodsOrder.setUpdatedBy(getCurrentUser().getUserName());
            this.incentiveGoodsOrderService.updateIncentiveGoodsOrder(incentiveGoodsOrder);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "修改IncentiveGoodsOrder失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 发放 IncentiveGoodsOrder
     *
     * @author zhangwei
     * @date 2024-09-02 11:28:06
     */
    @Log("发放IncentiveGoodsOrder")
    @PostMapping("incentiveGoodsOrder/handOut")
    @ResponseBody
    @RequiresPermissions("incentiveGoodsOrder:handOut")
    public FebsResponse handOutIncentiveGoodsOrder(@RequestBody IncentiveGoodsOrderDto incentiveGoodsOrderDto) throws FebsException {
        if(IncentiveRewardConstant.GOODS_ORDER_TYPE.OFFLINE.equals(incentiveGoodsOrderDto.getGoodsOrderType())){
            throw new FebsException("订单类型异常，请联系管理员！");
        }
        if(StringUtils.isBlank(incentiveGoodsOrderDto.getCode())){
            throw new FebsException("兑换码为空，请确认！");
        }
        if(!Objects.equals(incentiveGoodsOrderDto.getCode(),incentiveGoodsOrderDto.getExchangeCode())){
            throw new FebsException("兑换码与奖品兑换码不一致，请确认！");
        }
        if(incentiveGoodsOrderDto.getGoodsList().isEmpty()){
            throw new FebsException("奖品列表数据异常，请联系管理员！");
        }
        if(incentiveGoodsOrderDto.getUserList().isEmpty()){
            throw new FebsException("用户列表数据异常，请联系管理员！");
        }
        try {
            incentiveGoodsOrderDto.setCreatedBy(getCurrentUser().getUserName());
            this.incentiveGoodsOrderService.handOutIncentiveGoodsOrder(incentiveGoodsOrderDto);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "发放失败";
            String name = e.getClass().getName();
            if(FebsException.class.getName().equals(name)) {
                message = e.getMessage();
            }
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 取消发放 IncentiveGoodsOrder
     *
     * @author zhangwei
     * @date 2024-09-02 11:28:06
     */
    @Log("取消发放IncentiveGoodsOrder")
    @PostMapping("incentiveGoodsOrder/cancel")
    @ResponseBody
    @RequiresPermissions("incentiveGoodsOrder:cancel")
    public FebsResponse cancelIncentiveGoodsOrder(@RequestBody IncentiveGoodsOrderDto incentiveGoodsOrderDto) throws FebsException {
        if(!"2".equals(incentiveGoodsOrderDto.getGoodsOrderType())){
            throw new FebsException("订单类型异常，请联系管理员！");
        }
        if(incentiveGoodsOrderDto.getGoodsList().isEmpty()){
            throw new FebsException("奖品列表数据异常，请联系管理员！");
        }
        if(incentiveGoodsOrderDto.getUserList().isEmpty()){
            throw new FebsException("用户列表数据异常，请联系管理员！");
        }
        try {
            incentiveGoodsOrderDto.setCreatedBy(getCurrentUser().getUserName());
            this.incentiveGoodsOrderService.cancelIncentiveGoodsOrder(incentiveGoodsOrderDto);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "取消发放失败";
            log.error(message, e);
            throw new FebsException("".equals(e.getMessage()) || null == e.getMessage() ? message :e.getMessage());
        }
    }

}
